#!/user/bin/env python3
# -*- coding: utf-8 -*-
"""
--------------------------------------
    Author:     JiChao_Song
    Date  :     2020/12/24 9:22
    Desc  :
--------------------------------------
"""
import jsonpath
import time
from common.libs.FakerUtils import *
from requests.models import Response

from common.libs.SimpleRequestsUtils import SimpleRequesUtils
from servers.models.ApiCaseModel import ApiCase
from servers.servers.BaseServices import BaseServices
from servers.servers.HeadersServices import HeaderServices
from servers.servers.ProjectServices import ProjectServices
from servers.servers.VariableServices import VariableServices


class ApiCaseServices(BaseServices):

    def __init__(self, document=ApiCase):
        super().__init__(document)


class ApiCaseRun:
    """
    接口发送请求
    """

    def __init__(self, queryset: ApiCase):

        self.queryset = queryset
        self.projectService = ProjectServices()
        self.variableServices = VariableServices()
        self.headerServices = HeaderServices()
        self.projectId = self.queryset.projectId
        self.baseUrl = self.projectService.find_by_id(self.projectId).projectUrl
        self.url = self.baseUrl + self.queryset.apiPath
        self.data = {}

        # 是哦否断言成功
        self.isApiAssert = False

        # 判断参数是否提取成功
        self.isApiExtract = False

        self.result = None

    def set_apiParam(self):
        """
        设置参数
        :return:
        """
        if self.queryset.apiParam and len(self.queryset.apiParam) != 0:
            for i in self.queryset.apiParam:
                value = i.get('value')
                # 判断value的值必须为str
                if isinstance(value, str):
                    # 1. 判断是否使用变量  2. 判断是否是内置函数
                    if '$' in value and 'random' in value:
                        index = value.index('$')
                        self.data[i.get('key')] = f'{value[:index]}{eval(value[index + 1:])}'
                    # 3. 使用自定义变量
                    elif '$' in value:
                        index = value.index('$')
                        self.data[i.get('key')] = f'{value[:index]}' \
                                                  f'{self.variableServices.find_by_any(variableName = value[index + 1:], projectId = self.projectId)}'
                    else:
                        self.data[i.get('key')] = value
                else:
                    self.data[i.get('key')] = value

    def set_apiHeaders(self):
        """
        设置请求头
        :return:
        """
        # 如果需要请求头并且项目存在
        if self.queryset.isHeader:
            return self.headerServices.get_headers_dict(projectId = self.projectId)
        return None

    def set_apiAssert(self, response: Response):
        """
        断言
        :param response:
        :return:
        """

        if self.queryset.apiAssert and response:
            code = jsonpath.jsonpath(response.json(), f'$..{self.queryset.apiAssert.get("key")}')[0]
            if str(code) == self.queryset.apiAssert.get('value'):
                self.isApiAssert = True

    def set_apiExtract(self, response:Response):
        """
        参数提取
        :param response:
        :return:
        """

        if self.isApiAssert and self.queryset.apiExtract and len(self.queryset.apiExtract) > 0:
            for i in self.queryset.apiExtract:
                variableValue = jsonpath.jsonpath(response.json(), f'$..{i}')[0]
                self.variableServices.add_veriable(variableName = i, variableValue=str(variableValue), projectId = self.projectId)
            self.isApiExtract = True

    def request(self):

        self.set_apiParam()

        res  = SimpleRequesUtils(methods = self.queryset.apiMethod, url = self.url,
                                data =  self.data, headers = self.set_apiHeaders())

        response = res.send_requests()

        self.result = res.dictResult()

        self.set_apiAssert(response = response)

        self.set_apiExtract(response = response)


class SimpleApiCaseRun:

    def __init__(self, queryset: dict, projectId):
        self.queryset = queryset
        self.projectService = ProjectServices()
        self.variableServices = VariableServices()
        self.headerServices = HeaderServices()
        self.projectId = projectId
        self.baseUrl = self.projectService.find_by_id(self.projectId).projectUrl
        self.url = self.queryset.get('apiPath') if 'http' in self.queryset.get('apiPath') else self.baseUrl + self.queryset.get('apiPath')
        self.apiHeader = self.queryset.get('apiHeader')
        self.apiMethod = self.queryset.get('apiMethod')
        self.apiParam = self.queryset.get('apiParam')
        self.apiExtract = self.queryset.get('apiExtract')
        self.apiAssert = self.queryset.get('apiAssert')

        self.data = {}
        self.headers = {}

        # 是哦否断言成功
        self.isApiAssert = False

        # 判断参数是否提取成功
        self.isApiExtract = False

        self.result = {}

    def set_apiParam(self):
        """
        设置参数
        :return:
        """
        if self.apiParam and len(self.apiParam) != 0:
            for i in self.apiParam:
                value = i.get('value')
                # 判断value的值必须为str
                if isinstance(value, str):
                    # 1. 判断是否使用变量  2. 判断是否是内置函数
                    if '$' in value and 'random' in value:
                        index = value.index('$')
                        self.data[i.get('key')] = f'{value[:index]}{eval(value[index + 1:])}'
                    # 3. 使用自定义变量
                    elif '$' in value:
                        index = value.index('$')
                        self.data[i.get('key')] = f'{value[:index]}' \
                                                  f'{self.variableServices.find_by_any(variableName = value[index + 1:], projectId = self.projectId)}'
                    else:
                        self.data[i.get('key')] = value
                else:
                    self.data[i.get('key')] = value

    def set_apiAssert(self, response: Response):
        """
        断言
        :param response:
        :return:
        """

        if self.apiAssert and response:
            code = jsonpath.jsonpath(response.json(), f'$..{self.apiAssert.get("key")}')[0]
            if str(code) == self.apiAssert.get('value'):
                self.isApiAssert = True

    def set_apiExtract(self, response:Response):
        """
        参数提取
        :param response:
        :return:
        """

        if self.isApiAssert and self.apiExtract and len(self.apiExtract) > 0:
            for i in self.apiExtract:
                variableValue = jsonpath.jsonpath(response.json(), f'$..{i}')[0]
                self.variableServices.add_veriable(variableName = i, variableValue=str(variableValue), projectId = self.projectId)
            self.isApiExtract = True

    def set_apiHeaders(self):

        self.headers = self.headerServices.get_headers_dict(projectId = self.projectId)

        # if self.apiHeader and len(self.apiHeader) != 0:
        #     for i in self.apiHeader:
        #         value = i.get('value')
        #         # 判断value的值必须为str
        #         if isinstance(value, str):
        #             # 1. 判断是否使用变量  2. 判断是否是内置函数
        #             if '$' in value and 'random' in value:
        #                 index = value.index('$')
        #                 self.headers[i.get('key')] = f'{value[:index]}{eval(value[index + 1:])}'
        #             # 3. 使用自定义变量
        #             elif '$' in value:
        #                 index = value.index('$')
        #                 self.headers[i.get('key')] = f'{value[:index]}' \
        #                                           f'{self.variableServices.find_by_any(variableName = value[index + 1:], projectId = self.projectId)}'
        #             else:
        #                 self.headers[i.get('key')] = value
        #         else:
        #             self.headers[i.get('key')] = value

    def request(self):

        self.set_apiParam()

        self.set_apiHeaders()

        res  = SimpleRequesUtils(methods = self.apiMethod, url = self.url,
                                 data =  self.data, headers = self.headers)

        response = res.send_requests()

        self.result = res.dictResult()

        # self.set_apiAssert(response = response)

        # self.set_apiExtract(response = response)